import cannon, cursor, gamestate, igbuild, igfire, igplace, igtransition, wall
import worldmanager as wm
import os, pygame

class InGame(gamestate.GameState):
    """GameState for playing the actual game"""
    
    def __init__(self):
        #basic keybinds
        self.keybinds = {'to_pause': pygame.K_PAUSE,
                         'to_build_state': pygame.K_b,
                         'to_place_state': pygame.K_p,
                         'cursor_up': pygame.K_w,
                         'cursor_down': pygame.K_s,
                         'cursor_left': pygame.K_a,
                         'cursor_right': pygame.K_d}
        
        #key release keybinds
        self.upKeybinds = {
                           'cursor_up_kup': pygame.K_w,
                           'cursor_down_kup': pygame.K_s,
                           'cursor_left_kup': pygame.K_a,
                           'cursor_right_kup': pygame.K_d}
        
        #advanced keybinds
        self.keybindsAdv = {'dev_level_advance':
                            (pygame.K_0, (pygame.KMOD_CTRL, pygame.KMOD_ALT))}
        
        #link actions to appropriate function references
        self._actions = {'to_pause': self._action_to_pause,
                         'level_advance': self._action_level_advance,
                         'to_build_state': self._action_build_state,
                         'to_fire_state': self._action_fire_state,
                         'to_place_state': self._action_place_state,
                         'cursor_up': self._action_cursor_up,
                         'cursor_down': self._action_cursor_down,
                         'cursor_left': self._action_cursor_left,
                         'cursor_right': self._action_cursor_right,
                         'cursor_up_kup': self._action_cursor_up_kup,
                         'cursor_down_kup': self._action_cursor_down_kup,
                         'cursor_left_kup': self._action_cursor_left_kup,
                         'cursor_right_kup': self._action_cursor_right_kup}
        
        self._newState = self
        
        self.open_world()
        
        #controls order of progressing through internal states
        self._statesOrder = [[igtransition.IgTransition('trans_place'), 3000],
                             [igplace.IgPlace(), 5000],
                             [igtransition.IgTransition('trans_fire'), 3000],
                             [igfire.IgFire(), 8000],
                             [igtransition.IgTransition('trans_build'), 3000],
                             [igbuild.IgBuild(), 8000]]
        
        #track internal state and time spent in that state
        self.internalState = 0
        self.timeInState = 0
        
        #create and manage cursor object
        self.cursor = cursor.Cursor()
        
    def draw(self, screen):
        self.world.draw(screen)
        
        self._statesOrder[self.internalState][0].draw(screen)
        
        self.cursor.draw(screen)
            
    def enter_state(self):
        #TODO: check variable to determine if new game needs to be started
        
        self._newState = self
        
    def handle_events(self, events, mods):
        #let base class handle keydown events
        gamestate.GameState.handle_events(self, events, mods)
        
        #locally handle keyup events
        #duplicate code from base class event handling, modified to match
        #key up events
        for event in events:
            #keybind not found yet
            found = False
            
            if event.type == pygame.KEYUP:
                #check upKeybinds listing
                if not found:
                    for a in self.upKeybinds:
                        if event.key == self.upKeybinds[a]:
                            self._actions[a]()
                            break
    
    def update(self, etime):
        exit = False
        
        #increment time in current state
        self.timeInState += etime
        
        self.cursor.update()
        
        self._statesOrder[self.internalState][0].update(etime)
            
        #if all players failed to close walls... (give more rebuild time?)
        #if one or more players failed to close walls BUT more than one remains... (eliminate players then start next cycle)
        #if one player remains... (game is over)
        #if all players remain... (start next cycle)
        
        
        if exit:
            self._newState = gamestate.GameState.validStates['gameover']
        
        #if we've exceeded time in this state
        if self.timeInState > self._statesOrder[self.internalState][1]:
            #go to next state
            self.timeInState = 0
            self.internalState = (self.internalState + 1) % len(self._statesOrder)   
        
        return self._newState
        
    def _action_build_state(self):
        self.world.wallGroup.add(wall.Wall(self.world.mapKey[1], self.world.world[9][8].rect, (9, 8)))
        self.world.wallGroup.add(wall.Wall(self.world.mapKey[1], self.world.world[8][8].rect, (8, 8)))
        self.world.wallGroup.add(wall.Wall(self.world.mapKey[1], self.world.world[7][8].rect, (7, 8)))
        self.world.wallGroup.add(wall.Wall(self.world.mapKey[1], self.world.world[6][8].rect, (6, 8)))
        self.world.wallGroup.add(wall.Wall(self.world.mapKey[1], self.world.world[5][8].rect, (5, 8)))
        self.world.wallGroup.add(wall.Wall(self.world.mapKey[1], self.world.world[4][8].rect, (4, 8)))
        self.world.wallGroup.add(wall.Wall(self.world.mapKey[1], self.world.world[3][8].rect, (3, 8)))
        self.world.wallGroup.add(wall.Wall(self.world.mapKey[1], self.world.world[3][7].rect, (3, 7)))
        self.world.wallGroup.add(wall.Wall(self.world.mapKey[1], self.world.world[3][6].rect, (3, 6)))
        self.world.wallGroup.add(wall.Wall(self.world.mapKey[1], self.world.world[3][5].rect, (3, 5)))
        self.world.wallGroup.add(wall.Wall(self.world.mapKey[1], self.world.world[3][4].rect, (3, 4)))
        
    def _action_cursor_down(self):
        self.cursor.velY = 2
    
    def _action_cursor_down_kup(self):
        self.cursor.velY = 0
    
    def _action_cursor_left(self):
        self.cursor.velX = -2
    
    def _action_cursor_left_kup(self):
        self.cursor.velX = 0
    
    def _action_cursor_right(self):
        self.cursor.velX = 2
    
    def _action_cursor_right_kup(self):
        self.cursor.velX = 0
    
    def _action_cursor_up(self):
        self.cursor.velY = -2
    
    def _action_cursor_up_kup(self):
        self.cursor.velY = 0
        
    def _action_fire_state(self):
        pass
    
    def _action_level_advance(self):
        self._newState = gamestate.GameState.validStates['leveladvance']
        
    def _action_place_state(self):
        self.world.cannonGroup.add(cannon.Cannon(self.world.mapKey[2], self.world.world[6][6].rect, (6, 6)))
        self.world.cannonGroup.add(cannon.Cannon(self.world.mapKey[2], self.world.world[5][6].rect, (5, 6)))
        self.world.cannonGroup.add(cannon.Cannon(self.world.mapKey[2], self.world.world[4][6].rect, (4, 6)))
    
    def _action_to_pause(self):
        self._newState = gamestate.GameState.validStates['paused']
        
    def open_world(self):
        self.world = wm.WorldManager(os.path.join('maps', 'board1.map'))        